/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufpb.projetoesa.negocio;

import br.ufpb.projetoesa.exceptions.TurmaInexistenteException;
import br.ufpb.projetoesa.exceptions.ProfessorInexistenteException;
import br.ufpb.projetoesa.exceptions.AtualizacaoDeProfessorException;
import br.ufpb.projetoesa.exceptions.RemocaoDeAlunosImpossivelException;
import br.ufpb.projetoesa.exceptions.TurmaInvalidaException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Rennan
 */
public class Departamento {
    
    
    private List<Professor> professores;
    private List<Turma> turmas;
    
    
    public Departamento(){
        professores = new ArrayList<Professor>();
        turmas = new ArrayList<Turma>();
    }
    
    
    // --------------> Inicio: PROFESSOR
    
    
    /**
     * Adiciona um professor neste Departamento.
     * @param _p Professor a ser adicionado.
     */
    public void addProfessor(Professor _p){
        this.professores.add(_p);
    }

    /**
     * Retorna a lista de todos os professores cadastrados.
     * @return Lista de professores cadastrados no Departamento.
     */
    public List<Professor> getProfessores() {
        return this.professores;
    }
    
    
    /**
     * Pesquisa se existe um Professor pelo seu nome.
     * @param nome Nome do professor.
     * @return Professor que foi encontrado na busca.
     * @throws ProfessorInexistenteException 
     */
    public Professor getProfessorNome(String nome) throws ProfessorInexistenteException{
        for(Professor p: this.professores){
            if (p.getNome().equalsIgnoreCase(nome)) {
                return p;
            }
        }
        throw new ProfessorInexistenteException("Não foi encontrado nenhum Professor com o nome " + nome);
    }
    
    /**
     * Pesquisa se existe um Professor pela sua matrícula
     * @param mat Matricula do professor.
     * @return Professor
     * @throws ProfessorInexistenteException 
     */
    public Professor getProfessorMat(String mat) throws ProfessorInexistenteException{
        for(Professor p: this.professores){
            if (p.getMatricula().equals(mat)) {
                return p;
            }
        }
        throw new ProfessorInexistenteException("Não foi possível encontrar nenhum professor com a matrícula " + mat);
    }
    
    /**
     * Pesquisa evidências de professores cadastrados através da parte de seus
     * nomes e retorna uma lista com os resultados encontrados.
     * @param nome Nome ou partes de nome.
     * @return List<Professores> 
     */
    public List<Professor> pesquisaProfessores(String nome){
        System.out.println("nome = " + nome);
        List<Professor> resultado = new ArrayList<Professor>();
        for(Professor p: professores){
            System.out.println("p.getNome() = " + p.getNome());
            if (p.getNome().toUpperCase().startsWith(nome.toUpperCase())){
                resultado.add(p);
            }
        }
        return resultado;
    }
    
    
    /**
     * Atualiza um Professor devidamente cadastrado.
     * Recebe o Professor atual (profAtual) e atualiza inserindo o "profModificado". 
     * @param profAtual Professor que está no departamento.
     * @param profModificado Professor que foi modificado.
     * @throws AtualizacaoDeProfessorException 
     */
    public void atualizaProfessor(Professor profAtual, Professor profModificado) 
            throws AtualizacaoDeProfessorException{
        
        if (profAtual != null && profModificado != null){
            if (professores.contains(profAtual)){
                professores.remove(profAtual);
                professores.add(profModificado);
            } else {
                throw new AtualizacaoDeProfessorException("Não foi possível encontrar o professor e atualizar seus dados,"
                        + "verifique e tente novamente.");
            }
        } else {
            throw new AtualizacaoDeProfessorException("Ocorreu um erro ao tentar atualizar os dados do professor,"
                    + " verifique as informações e tente novamente.");
        }
        
    }
    
    /**
     * Remove um professor do departamento.
     * @param prof Professor a ser removido.
     * @throws ProfessorInexistenteException 
     */
    public void removerProfessor(Professor prof) throws ProfessorInexistenteException{
        for(Professor p: this.professores){
            if(p.equals(prof)){
                this.professores.remove(p);
                return;
            }
            
        }
        throw new ProfessorInexistenteException("Não foi possível remover o professor.");
        
    }
    
    /**
     * Remove um professor de um departamento pelo nome.
     * @param nome Nome do professor que se quer remover.
     * @throws ProfessorInexistenteException 
     */
    public void removerProfessorNome(String nome) throws ProfessorInexistenteException{
        for(Professor p : this.professores){
            if(p.getNome().equals(nome)){
                this.professores.remove(p);
                return;
            }
        }
        throw new ProfessorInexistenteException("Não foi possível remover o professor.");
    }

    /**
     * Remove um professor do departamento pela matrícula.
     * @param matricula Matrícula do professor que se quer remover.
     * @throws ProfessorInexistenteException 
     */
     public void removerProfessorMatricula(String matricula)throws ProfessorInexistenteException{
        for(Professor p : this.professores){
            if(p.getMatricula().equals(matricula))
                this.professores.remove(p);
            return;
        }
        throw new ProfessorInexistenteException("Não foi possível remover o professor.");
    }

     // --------------> Fim: PROFESSOR 
     
    
     
    
    // --------------> Inicio: TURMA
    
     /**
      * Adiciona uma nova turma nesta classe. Se a turma não tiver sido
      * instanciada, uma exceção será lançada.
      * @param turma Turma que será adicionada a Lista de Turmas do departamento.
      * @throws TurmaInvalidaException 
      */
    public void addTurma(Turma turma) throws TurmaInvalidaException {
        if (turma != null)
            turmas.add(turma);
        else
            throw new TurmaInvalidaException("Ocorreu um erro ao tentar cadastrar a turma! \n"
                    + "Verifique e tente novamente.");
    }
    
    /**
     * Adiciona uma nova turma nesta classe. Se a turma não tiver sido
     * instanciada, uma exceção será lançada.
     * @param id Código identificador da Turma.
     * @throws TurmaInvalidaException 
     */
    public void addTurma(String id) throws TurmaInvalidaException {
        if (id != null) {
            Turma t = new Turma(id);
            turmas.add(t);
        } else {
            throw new TurmaInvalidaException("Ocorreu um erro ao tentar cadastrar a turma! \n"
                    + "Verifique e tente novamente.");
        }
    }
    
    /**
     * Adiciona uma nova turma nesta classe. Se a turma não tiver sido
     * instanciada, uma exceção será lançada.
     * @param id Código identificador da Turma.
     * @param qtdAlunos Quantidade de alunos da Turma.
     * @throws TurmaInvalidaException 
     */
    public void addTurma(String id, int qtdAlunos) throws TurmaInvalidaException {
        if (id != null && qtdAlunos > 3) { // verificar a regra de negócio!
            Turma t = new Turma(id, qtdAlunos);
            turmas.add(t);
        } else {
            throw new TurmaInvalidaException("Ocorreu um erro ao tentar cadastrar a turma! \n"
                    + "Verifique e tente novamente.");
        }
    }
    
    
    /**
     * Retorna uma estrutura List contendo todas as Turmas cadastradas.
     * @return Lista com todas as Turmas pestencentes ao departamento.
     */
    public List<Turma> getTurmas(){
        return this.turmas;
    }
    
    
    /**
     * Método responsável por remover uma turma por sua id, se não existir retornar mensagem.
     * @param id Código de identificação da Turma.
     * @throws TurmaInexistenteException 
     */
    public void removerTurma(String id) throws TurmaInexistenteException{
        
        for(Turma turma: this.turmas){
            
            if(turma.getID().equals(id)){
                this.turmas.remove(turma);
                return;
            }
        }
        throw new TurmaInexistenteException("Essa turma " + id + " não foi encontrada");
        
        
    }
    
    
    /**
     * Remove uma Turma deste Departamento.
     * @param t Uma entidade Turma a ser removida.
     * @throws TurmaInexistenteException
     * @throws TurmaInvalidaException 
     */
    public void removerTurma(Turma t) throws TurmaInexistenteException, 
            TurmaInvalidaException{
        
        if (t != null) {
            if (turmas.contains(t)){
                turmas.remove(t);
            } else {
                throw new TurmaInexistenteException("Esta turma não está cadastrada no sistema.");
            }
        } else {
            throw new TurmaInvalidaException("Não foi possível remover a Turma especificada. \n"
                    + "Verifique e tente novamente.");
        }
        
    }
    
    /**
     * Atualiza uma Turma cadastrada neste Departamento. Para isso, é necessário
     * receber uma instância da Turma a ser modificada e uma nova instância da
     * Turma (atualizada).
     * @param t1 Turma obsoleta.
     * @param t2 nova Turma.
     * @throws TurmaInexistenteException
     * @throws TurmaInvalidaException 
     */
    public void atualizaTurma(Turma t1, Turma t2) throws TurmaInexistenteException, 
            TurmaInvalidaException {
        
        if (t1 != null && t2 != null) {
            if (turmas.contains(t1)){
                turmas.remove(t1);
                turmas.add(t2);
            } else {
                throw new TurmaInexistenteException("Ocorreu um erro na atualização da Turma. Talvez seja \n"
                        + "necessário verificar novamente os parâmetros de entrada.");
            }
        } else {
            throw new TurmaInvalidaException("Ocorreu um erro ao tentar atualizar a Turma. \n"
                    + "Verifique e tente novamente.");
        }
        
    }
//    
//    public void atualizaQtdAlunosEmTurma(){
//        
//    }
    
    
    /**
     * Procura por uma determinada Turma de acordo com sua identificação
     * @param id Código identificador da turma.
     * @return Turma da lista do Departamento, quando encontrada.
     * @throws TurmaInexistenteException 
     */
    public Turma getTurmaID(String id) throws TurmaInexistenteException{
        for(Turma t: this.turmas){
            if(t.getID().equals(id))
                return t;
        }
        throw new TurmaInexistenteException("Nenhuma turma com a identificação " + id + " foi encontrada.");
    }
    
    
    /**
     * Verifica se existe esta Turma está cadastrada.
     * @param Turma
     * @return boolean indicando se existe esta Turma 
     * @throws TurmaInexistenteException 
     */
    public boolean containsTurma(Turma turma){
        if (this.turmas.contains(turma))
            return true;
        return false;
    }
    
    // ATENÇÃO: Esse método estava sendo duplicado com o getTurmaID()
//    /**
//     * Retorna uma Turma correspondendo ao "id" recebido como parâmetro.
//     * @param id Código identificador da Turma.
//     * @return Turma encontrada na lista de Turmas.
//     * @throws TurmaInexistenteException 
//     */
//    public Turma getTurma(String id) throws TurmaInexistenteException {
//        for(Turma t: this.turmas)
//            if (t.getID().equals(id))
//                return t;
//        throw new TurmaInexistenteException("Não existe nenhuma Turma com o ID: " + id + " cadastrada\n"
//                + "neste Departamento.");
//    }
    
    
    // -------------> Fim: TURMA
    
    
    
    // -------------> Inicio: ALUNO
    
    /**
     * Percorre a lista de turmas cadastradas até encontrar ou não uma
     * Turma com sua ID igual ao "id" recebido no parâmetro, e então
     * chama o método da Turma encontrada afim de remover uma certa
     * quantidade (qtd) de alunos já cadastrados.
     * @param id Código identificador da turma.
     * @param qtd Quantidade de alunos a ser removida.
     * @throws TurmaInexistenteException
     * @throws RemocaoDeAlunosImpossivelException 
     */
    public void removerAlunos(String id, int qtd) throws TurmaInexistenteException, RemocaoDeAlunosImpossivelException{
        for(Turma t: this.turmas){
            if(t.getID().equals(id)) {
                t.removerAlunos(qtd);
                return;
            }
        }
        throw new TurmaInexistenteException("Nenhuma turma com a identicação " + id + " foi encontrada.");
    }
    
    // -------------> Fim: ALUNO
    
}
